#include "Renderer2d.h"

Renderer2d::Renderer2d() : IKernelTask( "Renderer2d", 20 )
{
 	logger << "Constructing object" << std::endl;
}

Renderer2d::~Renderer2d()
{
	logger << "Destructing object" << std::endl;
}

GCPtr<Renderer2d> Renderer2d::getInstance()
{
	static GCPtr<Renderer2d> renderer = new Renderer2d();
	return renderer;
}

bool Renderer2d::Start()
{
	return init();
}

void Renderer2d::Stop()
{
	if( surf_screen )
	{
		SDL_FreeSurface( surf_screen );
		surf_screen = 0;
	}

	SDL_Quit();
}

void Renderer2d::Update()
{
	for each (CUnit* unit in vRenderables)
	{
		draw( surf_screen, unit->unitImage, static_cast<int>(unit->xPos), static_cast<int>(unit->yPos) );
	}
	
	SDL_Flip( surf_screen );
}

bool Renderer2d::init()
{
	width = XMLSettings::getInstance().getResolution().w;
	height = XMLSettings::getInstance().getResolution().h;
	bitDepth = XMLSettings::getInstance().getBitDepth();

	if( SDL_Init( SDL_INIT_VIDEO < 0 ) )
	{
		logger << "SDL_Init failed" << std::endl;
		system( "Pause" );
		return false;
	}

	// Sets the video mode and checks if it succeeded
	if( ( surf_screen = SDL_SetVideoMode( width, height, bitDepth, SDL_SWSURFACE) ) == NULL )
	{
		logger << "SDL_SetVideoMode failed" << std::endl;
		system( "Pause" );
		return false;
	}
	return true;
}

// Draws part of the image
bool Renderer2d::draw( SDL_Rect* src_rect, SDL_Surface* surf_dest, SDL_Surface* surf_src, int x, int y )
{
	if(  surf_src == NULL ){
		logger << "No valid source surface" << std::endl;
		return false;
	}

	if( surf_dest == NULL ){
		logger << "No valid destination surface" << std::endl;
		return false;
	}

	// An SDL structure, has the attributes for a rectangle
	// This is the destination rectangle
	SDL_Rect destRect;

	// Here we assign the x and y values, so we know where to draw.
	// We do not assign the w and h values, because we do not worry
	// about the size, only where we are going to draw.
	destRect.x = x;
	destRect.y = y;

	SDL_BlitSurface( surf_src, src_rect, surf_dest, &destRect );

	return true;
}

// Draws the whole image
bool Renderer2d::draw( SDL_Surface* surf_dest, SDL_Surface* surf_src, int x, int y )
{
	// Checks if we have valid surfaces, if not, return false
	if( surf_dest == NULL || surf_src == NULL ){
		logger << "No valid surface to use" << std::endl;
		return false;
	}

	// An SDL structure, has the attributes for a rectangle
	SDL_Rect destRect;

	// Here we assign the x and y values, so we know where to draw.
	// We do not assign the w and h values, because we do not worry
	// about the size, only where we are going to draw.
	destRect.x = x;
	destRect.y = y;

	// The actual function to draw the image
	SDL_BlitSurface( surf_src, NULL, surf_dest, &destRect );

	return true;
}

void Renderer2d::colorKeying( SDL_Surface* surface )
{
	Uint32 colorkey = SDL_MapRGB( surface->format, 0x00, 0x00, 0x00 );
	SDL_SetColorKey( surface, SDL_SRCCOLORKEY, colorkey );
}

void Renderer2d::addRenderable( CUnit* unit )
{
	vRenderables.push_back(unit);
}

void Renderer2d::removeRenderable( CUnit* unit )
{
	// remove renderables when no longer in use
	// TODO: implement
}
